package com.knight.id;

import com.knight.id.annotation.KnightID;
import com.knight.id.util.SnowflakeIdUtil;
import com.knight.id.util.UUIdUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;

import java.lang.reflect.Field;
import java.util.*;

@Intercepts({@Signature(type = Executor.class, method = "update",args = {MappedStatement.class, Object.class})})
@SuppressWarnings({"rawtypes", "unchecked"})
public class IdInterceptor implements Interceptor {

    private SnowflakeIdUtil snowflakeIdUtil;

    //主键生成类型 1-雪花算法生成 2-UUID生成
    private int type;


    public IdInterceptor(SnowflakeIdUtil snowflakeIdUtil) {
        this.snowflakeIdUtil = snowflakeIdUtil;
    }

    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement =  (MappedStatement)invocation.getArgs()[0]; // 获取MappedStatement
        Object param = invocation.getArgs()[1]; //获取入参
        //确定当前是insert语句
        if(SqlCommandType.INSERT.equals(mappedStatement.getSqlCommandType())) {
            Set<Object> paramSet = new HashSet<Object>();//入参集合
            //获取全部参数
            if(param instanceof Map) {
                Collection list = (Collection)((Map) param).get("list");
                for(Object value : list) {
                    if(value instanceof Collection) {
                        paramSet.addAll((Collection)value);
                    }else {
                        paramSet.add(value);
                    }
                }
            }else {
                paramSet.add(param);
            }

            for(Object object : paramSet) {
                Class clazz = object.getClass();
                List<Field> fieldList = Arrays.asList(clazz.getDeclaredFields());
                for(Field field : fieldList) {
                    if(field.isAnnotationPresent(KnightID.class)) { //确定当前字段是否被KnightID注解修饰
                        field.setAccessible(true);
                        if(field.getType().isInstance(Long.class)) {
                            field.set(object,snowflakeIdUtil.nextId()); //进行雪花ID赋值
                        }
                        if(field.getType().isInstance(String.class)) {
                            Long id = snowflakeIdUtil.nextId();
                            field.set(object,id.toString()); //进行雪花ID赋值
                        }

                    }
                }
            }

        }

        return invocation.proceed();//原逻辑
    }

    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }

    public void setProperties(Properties properties) {

    }
}
